package comp9417;

import java.io.Console;
import java.io.FileNotFoundException;
import java.util.Map;

/**
 * Created by huy on 3/06/14.
 */
public class Evaluation {

    private Console console;
    private int minK = 2;
    private int maxK = 10;
    private int folds = 10;
    private boolean weighted = false;

    public Evaluation(Console console) {
        this.console = console;
    }

    public static void main(String[] args) throws FileNotFoundException {
        Console console = System.console();
        if (console == null) {
            System.out.println("Cannot start console.");
            System.exit(0);
        }
        Evaluation evaluation = new Evaluation(console);
        evaluation.go();
    }

    private void go() throws FileNotFoundException {
        int option = 1;
        Dataset dataset = null;
        Evaluator evaluator = null;
        while (option > 0) {
            if (option <= 1) {
                console.printf("Enter data arff data file:");
                String fileName = console.readLine();
                dataset = new DataLoader().loadClassificationData(fileName);
            }
            if (option <= 2) {
                console.printf("Loaded dataset with %d datapoints. The followings are the attributes found: \n", dataset.getDatapoints().size());
                for (Attribute attribute : dataset.getAttributes()) {
                    console.printf("%s\n", attribute.name);
                }
                console.printf("Enter attribute to predict/classify:");
                String attribute = console.readLine();
                evaluator = new Evaluator(dataset, attribute);
            }
            if (option <= 3) {
                minK = parseInteger("Enter minimum k [%d]:", minK);
                console.printf("User picked: %d\n", minK);
                maxK = parseInteger("Enter maximum k [%d]:", maxK);
                console.printf("User picked: %d\n", maxK);
                folds = parseInteger("Enter number of folds [%d]:", folds);
                console.printf("User picked: %d\n", folds);
                weighted = parseBoolean("Use weighted distance [%b]:", weighted);
                console.printf("User picked: %b\n", weighted);
                console.printf("Best k for this dataset is: %d\n", evaluator.bestK(minK, maxK, folds, weighted));
                console.printf("Statistic: \n");
                console.printf("k | Error\n");
                for (Map.Entry<Integer, Double> entry : evaluator.getStats().entrySet()) {
                    console.printf("%2d | %f\n", entry.getKey(), entry.getValue());
                }
            }
            option = parseInteger("Do you want to 0) exit 1) load new dataset, 2) change attribute or 3) change settings:\n", 0);
        }
    }

    private boolean parseBoolean(String prompt, boolean defaultValue) {
        console.printf(prompt, defaultValue);
        return Boolean.parseBoolean(console.readLine().trim());
    }

    private int parseInteger(String prompt, int defaultValue) {
        int parsed;
        try {
            console.printf(prompt, defaultValue);
            parsed = Integer.parseInt(console.readLine().trim());
        } catch (NumberFormatException ex) {
            parsed = defaultValue;
        }
        return parsed;
    }
}
